#ifndef TOUCHKEYBOARD_H
#define TOUCHKEYBOARD_H

#include <QWidget>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QLineEdit>
#include <QTextEdit>
#include <QPlainTextEdit>
#include <QComboBox>
#include <QMouseEvent>
#include <QPoint>
#include <QLabel>
#include <QPropertyAnimation>
#include <QGraphicsDropShadowEffect>
#include <QMap>
#include <QTimer>
#include <QFile>
#include <QTextStream>
#include <QTouchEvent>
#include <QDir>
#include <QPushButton>
#include "keyboardbutton.h"

// 定义通用文本接口
class TextInterface {
public:
    virtual ~TextInterface() = default;
    virtual void insertText(const QString& text) = 0;
    virtual void backspace() = 0;
    virtual void clear() = 0;
    virtual QString text() const = 0;
    virtual void setFocus() = 0;
    virtual QPoint mapToGlobal(const QPoint& pos) const = 0;
    virtual QSize size() const = 0;
    virtual void moveCursorToEnd() = 0;
};

// QLineEdit适配器
class LineEditTextInterface : public TextInterface {
public:
    LineEditTextInterface(QLineEdit* lineEdit) : m_lineEdit(lineEdit) {}
    
    void insertText(const QString& text) override {
        m_lineEdit->insert(text);
    }
    
    void backspace() override {
        m_lineEdit->backspace();
    }
    
    void clear() override {
        m_lineEdit->clear();
    }
    
    QString text() const override {
        return m_lineEdit->text();
    }
    
    void setFocus() override {
        m_lineEdit->setFocus();
    }
    
    QPoint mapToGlobal(const QPoint& pos) const override {
        return m_lineEdit->mapToGlobal(pos);
    }
    
    QSize size() const override {
        return m_lineEdit->size();
    }
    
    void moveCursorToEnd() override {
        m_lineEdit->setCursorPosition(m_lineEdit->text().length());
    }

private:
    QLineEdit* m_lineEdit;
};

// QTextEdit适配器
class TextEditTextInterface : public TextInterface {
public:
    TextEditTextInterface(QTextEdit* textEdit) : m_textEdit(textEdit) {}
    
    void insertText(const QString& text) override {
        if (m_textEdit) m_textEdit->insertPlainText(text);
    }
    
    void backspace() override {
        if (m_textEdit) m_textEdit->textCursor().deletePreviousChar();
    }
    
    void clear() override {
        if (m_textEdit) m_textEdit->clear();
    }
    
    QString text() const override {
        return m_textEdit ? m_textEdit->toPlainText() : QString();
    }
    
    void setFocus() override {
        if (m_textEdit) m_textEdit->setFocus();
    }
    
    QPoint mapToGlobal(const QPoint& pos) const override {
        return m_textEdit ? m_textEdit->mapToGlobal(pos) : QPoint();
    }
    
    QSize size() const override {
        return m_textEdit ? m_textEdit->size() : QSize();
    }
    
    void moveCursorToEnd() override {
        if (m_textEdit) m_textEdit->moveCursor(QTextCursor::End);
    }

private:
    QTextEdit* m_textEdit;
};

// QPlainTextEdit适配器
class PlainTextEditTextInterface : public TextInterface {
public:
    PlainTextEditTextInterface(QPlainTextEdit* plainTextEdit) : m_plainTextEdit(plainTextEdit) {}
    
    void insertText(const QString& text) override {
        if (m_plainTextEdit) m_plainTextEdit->insertPlainText(text);
    }
    
    void backspace() override {
        if (m_plainTextEdit) m_plainTextEdit->textCursor().deletePreviousChar();
    }
    
    void clear() override {
        if (m_plainTextEdit) m_plainTextEdit->clear();
    }
    
    QString text() const override {
        return m_plainTextEdit ? m_plainTextEdit->toPlainText() : QString();
    }
    
    void setFocus() override {
        if (m_plainTextEdit) m_plainTextEdit->setFocus();
    }
    
    QPoint mapToGlobal(const QPoint& pos) const override {
        return m_plainTextEdit ? m_plainTextEdit->mapToGlobal(pos) : QPoint();
    }
    
    QSize size() const override {
        return m_plainTextEdit ? m_plainTextEdit->size() : QSize();
    }
    
    void moveCursorToEnd() override {
        if (m_plainTextEdit) m_plainTextEdit->moveCursor(QTextCursor::End);
    }

private:
    QPlainTextEdit* m_plainTextEdit;
};

// QComboBox适配器
class ComboBoxTextInterface : public TextInterface {
public:
    ComboBoxTextInterface(QComboBox* comboBox) : m_comboBox(comboBox) {}
    
    void insertText(const QString& text) override {
        if (m_comboBox && m_comboBox->lineEdit()) {
            m_comboBox->lineEdit()->insert(text);
        }
    }
    
    void backspace() override {
        if (m_comboBox && m_comboBox->lineEdit()) {
            m_comboBox->lineEdit()->backspace();
        }
    }
    
    void clear() override {
        if (m_comboBox && m_comboBox->lineEdit()) {
            m_comboBox->lineEdit()->clear();
        }
    }
    
    QString text() const override {
        if (!m_comboBox) return QString();
        if (m_comboBox->lineEdit()) {
            return m_comboBox->lineEdit()->text();
        }
        return m_comboBox->currentText();
    }
    
    void setFocus() override {
        if (m_comboBox) m_comboBox->setFocus();
    }
    
    QPoint mapToGlobal(const QPoint& pos) const override {
        return m_comboBox ? m_comboBox->mapToGlobal(pos) : QPoint();
    }
    
    QSize size() const override {
        return m_comboBox ? m_comboBox->size() : QSize();
    }
    
    void moveCursorToEnd() override {
        if (m_comboBox && m_comboBox->lineEdit()) {
            m_comboBox->lineEdit()->setCursorPosition(m_comboBox->lineEdit()->text().length());
        }
    }

private:
    QComboBox* m_comboBox;
};

class TouchKeyboard : public QWidget
{
    Q_OBJECT

public:
    enum KeyboardMode {
        SimpleMode,     // 简洁模式 - 数字和基本运算
        FullMode        // 全键盘模式 - 完整键盘
    };

    explicit TouchKeyboard(QWidget *parent = nullptr);
    virtual ~TouchKeyboard();

    // 显示/隐藏键盘 - 通用接口
    void showKeyboard(TextInterface* textInterface);
    void showKeyboard(QLineEdit *inputField = nullptr);
    void showKeyboard(QTextEdit *textEdit = nullptr);
    void showKeyboard(QPlainTextEdit *plainTextEdit = nullptr);
    void showKeyboard(QComboBox *comboBox = nullptr);
    void hideKeyboard();
    bool isVisible() const;

    // 模式切换
    void setMode(KeyboardMode mode);
    KeyboardMode getMode() const;

    // 智能定位
    void positionRelativeToInput(TextInterface* textInterface);
    void positionRelativeToInput(QLineEdit *inputField);
    void positionRelativeToInput(QTextEdit *textEdit);
    void positionRelativeToInput(QPlainTextEdit *plainTextEdit);
    void positionRelativeToInput(QComboBox *comboBox);
    
    // 设置目标输入框
    void setTargetInput(TextInterface* textInterface);
    void setTargetInput(QLineEdit *input);
    void setTargetInput(QTextEdit *textEdit);
    void setTargetInput(QPlainTextEdit *plainTextEdit);
    void setTargetInput(QComboBox *comboBox);
    TextInterface* getTargetInputInterface() const;
    
    // 向后兼容的getter方法
    QLineEdit* getTargetInput() const;
    QTextEdit* getTargetTextEdit() const;

signals:
    void keyPressed(const QString &key);
    void modeChanged(KeyboardMode mode);
    void keyboardHidden();

public slots:
    virtual void onKeyPressed(const QString &key);
    void onModeToggle();
    void onLanguageToggle();
    void onShiftToggle();

protected:
    // 初始化UI
    virtual void initializeUI();
    virtual void createSimpleLayout() = 0;
    virtual void createFullLayout() = 0;
    
    // 辅助方法
    void clearLayout();
    void setupWindowProperties();
    void addDropShadow();
    
    // 输入状态检查和更新
    void updateEnterButtonState();
    void checkInputContent();
    
    // 屏幕适配相关
    QSize getScreenSize() const;
    QSize calculateKeyboardSize() const;
    int calculateButtonSize() const;
    int calculateSpacing() const;
    
    // 数学表达式计算
    QString evaluateExpression(const QString &expression);
    double evaluateSimpleExpression(const QString &expr);
    
    // 中文输入相关
    void initChineseCandidates();
    bool loadPinyinDictFromFile(const QString &filePath);
    void loadDefaultPinyinMap();
    void updateCandidateDisplay();
    void selectCandidate(int index);
    void nextPage();
    void previousPage();
    QString getPinyinCandidates(const QString &pinyin);
    void calculateMaxCandidateCount();
    void updateHideButtonPosition();
    void updateLanguageButtonText();
    void updateDragHintLabelPosition();
    
    // 事件处理函数
    void mousePressEvent(QMouseEvent *event) override;
    void mouseMoveEvent(QMouseEvent *event) override;
    void mouseReleaseEvent(QMouseEvent *event) override;
    void touchEvent(QTouchEvent *event);
    void paintEvent(QPaintEvent *event) override;
    void showEvent(QShowEvent *event) override;
    void resizeEvent(QResizeEvent *event) override;
    bool eventFilter(QObject *obj, QEvent *event) override;
    bool event(QEvent *event) override;
    void enterEvent(QEvent *event) override;
    void leaveEvent(QEvent *event) override;
    
    // 成员变量 - 供派生类访问
    QVBoxLayout *m_mainLayout;
    QWidget *m_keyboardArea;
    QHBoxLayout *m_headerLayout;
    KeyboardButton *m_modeButton;
    KeyboardButton *m_hideButton;
    
    KeyboardMode m_currentMode;
    QLineEdit *m_targetInput;  // 向后兼容的QLineEdit指针
    QTextEdit *m_targetTextEdit;  // 向后兼容的QTextEdit指针
    TextInterface* m_targetInputInterface;  // 通用文本接口
    
    // 适配器管理
    PlainTextEditTextInterface* m_plainTextAdapter;
    ComboBoxTextInterface* m_comboBoxAdapter;
    
    // 大小写状态
    bool m_isCapitalized;
    
    // 中英文状态
    bool m_isChineseMode;
    
    // 中文输入相关
    QString m_currentPinyin;
    QStringList m_currentCandidates;
    int m_currentPage;
    QList<QPushButton*> m_candidateButtons;
    QWidget *m_candidateArea;
    QLabel *m_pinyinLabel;
    int m_maxCandidateCount;
    
    // 回车键按钮引用（用于更新状态）
    KeyboardButton *m_enterButton;
    
    // 拼音到汉字的映射表
    QMap<QString, QString> pinyinMap;
    
    // 语言切换按钮引用（用于更新文字显示）
    KeyboardButton *m_languageButton;
    
    // 拖拽相关
    bool m_isDragging;
    QPoint m_dragStartPosition;
    QPoint m_windowStartPosition;
    
    // 动画
    QPropertyAnimation *m_showAnimation;
    QPropertyAnimation *m_hideAnimation;
    
    // 防止重复显示的标志位
    bool m_isHiding;
    qint64 m_lastHideTime;
    
    // 输入框内容监控定时器
    QTimer *m_inputMonitorTimer;
    QString m_lastInputText;
};

#endif // TOUCHKEYBOARD_H